package deepbrain.simnetwork.mechanism;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class BayesianJointVariableState implements Cloneable {

	private Set<BayesianVariableState> variableStates = new HashSet<BayesianVariableState>();

	public BayesianJointVariableState addVariableState(String variable,
			boolean state) {
		variableStates.add(new BayesianVariableState(variable, state));
		return this;
	}

	@Override
	public int hashCode() {
		return variableStates.hashCode();
	}

	@Override
	public boolean equals(Object obj) {

		if (!(obj instanceof BayesianJointVariableState))
			return false;

		BayesianJointVariableState o = (BayesianJointVariableState) obj;

		return variableStates.equals(o.variableStates);

	}

	@Override
	public BayesianJointVariableState clone() {
		BayesianJointVariableState jointVariableState = new BayesianJointVariableState();
		jointVariableState.variableStates.addAll(this.variableStates);
		return jointVariableState;
	}

	@Override
	public String toString() {
		List<BayesianVariableState> list = new ArrayList<BayesianVariableState>(
				variableStates);
		Collections.sort(list);
		StringBuilder builder = new StringBuilder("(");
		for (int i = 0; i < list.size(); i++) {
			builder.append(list.get(i).state ? "+" : "-");
			builder.append(list.get(i).variable);
			if (i < list.size() - 1)
				builder.append(",");
		}
		builder.append(")");
		return builder.toString();
	}
}

class BayesianVariableState implements Comparable<BayesianVariableState> {

	public final String variable;
	public final boolean state;

	public BayesianVariableState(String variable, boolean state) {
		this.variable = variable;
		this.state = state;
	}

	public int compareTo(BayesianVariableState o) {
		return variable.compareTo(o.variable);
	}

	@Override
	public int hashCode() {
		return variable.hashCode() + (state ? 1 : 0);
	}

	@Override
	public boolean equals(Object obj) {

		if (!(obj instanceof BayesianVariableState))
			return false;

		BayesianVariableState o = (BayesianVariableState) obj;
		
		if (this.variable.equals(o.variable) && this.state == o.state)
			return true;

		return false;
	}

}
